<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Exarcheia</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript">
var ex = function() {
return {
	BASE_URL: '/value/-',
	KEY_PRE: 'exarcheia',
	WS_RE: /^\s*$/,
	NL_RE: /\n/g,
	ALNUM_RE: /[a-zA-Z0-9\.]/,
	DEF_V_CAP: '',
	DEF_ERR: 'An error has occured. Please try again later.',
	TTL: null,
	CHK_EXIST: false,
	HIDE_EDIT: false,
	_curReq: null,
	_lastData: null,
	init: function() {
		$('#rF').hide();
		$('#wF').hide();
		if (ex.HIDE_EDIT) {
			$('#toolbar #editL').hide();
		}
		ex._hLoading();
		$("#commonF #fetchBut").click(function() {
			return ex.fetch();
		});
		$("#rF #editL").click(function() {
			return ex.edit();
		});
		$("#wF #saveBut").click(function() {
			return ex.w();
		});
		$("#wF #cancelBut").click(function() {
			return ex.cancelWrite();
		});
		ex.DEF_V_CAP = $('#wF #exValueLabel').html();
		u = document.location.toString();
		if (u.indexOf('?') != -1) {
			$('#exKey').val(unescape(u.substr(u.lastIndexOf('?')+1)));
			ex.r();
		}
	},
	exists: function(exKey) {
		var ret = false;
		$.ajax({
			type: 'HEAD',
			async: false,
			url: ex.BASE_URL + '/' + ex.KEY_PRE + '/' + exKey,
			success: function(data) { ret = true; },
			error: function (xhr, textStatus, errorThrown) { ret = false; }
		});
		return ret;
	},
	edit: function() {
		ex._rWrite(ex._lastData, true, "Edit the text below and click 'Save'");
		return false;
	},
	fetch: function() {
		u = document.location.toString();
		if (u.indexOf('?') != -1) {
			u = u.substr(0, u.lastIndexOf('?'));
		}
		document.location = u + '?' + escape($('#exKey').val());
	},
	r: function() {
		if (ex._curReq) {
			ex._curReq.abort();
			ex._curReq = null;
		}
		$('#rF').hide();
		$('#wF').hide();
		
		var exKey = ex.normKey($('#exKey').val());
		if (!exKey) {
			ex._rReadErr('');
			return false;
		}
		ex._clearErrs();
		ex._sLoading();
		ex._curReq = $.ajax({
			type: 'GET',
			url: ex.BASE_URL + '/' + ex.KEY_PRE + '/' + exKey,
			success: function(data) {
				ex._lastData = data;
				ex._rRead(data);
			},
			error: function (xhr, textStatus, errorThrown) {
				ex._lastData = null;
				if (xhr.status == 404) {
					ex._rWrite('');
				}
				else {
					ex._rReadErr();
				}
			},
			complete: function(xhr, textStatus) {
				ex._hLoading();
				ex._curReq = null;
			}
		});
		return false;
	},
	cancelWrite: function() {
		ex._rRead(ex._lastData);
		return false;
	},
	w: function() {
		if (ex._curReq) {
			ex._curReq.abort();
			ex._curReq = null;
		}
		$('#rF').hide();
		var exKey = ex.normKey($('#exKey').val());
		var exValue = $('#exValue').val();
		if (!exKey) {
			ex._rWriteErr('');
			return false;
		}
		else if (ex.CHK_EXIST && ex.exists(exKey)) {
			ex._rWriteErr('This exists. Please choose another.', '');
			return false;
		}
		else if (!exValue || exValue.match(ex.WS_RE)) {
			ex._rWriteErr('Please enter a value...');
			return false;
		}
		$('#wF').hide();
		ex._clearErrs();
		ex._sLoading();
		ex._curReq = $.ajax({
			type: 'POST',
			url: ex.BASE_URL,
			data: ex.TTL ? {
				key: ex.KEY_PRE + '/' + exKey,
				value: exValue,
				ttl: ex.TTL
			}:{
				key: ex.KEY_PRE + '/' + exKey,
				value: exValue,
			}
			,
			success: function(data) {
				ex._lastData = exValue;
				ex._rRead(data);
			},
			error: function (xhr, textStatus, errorThrown) {
				if (xhr.status == 404) {
					ex._lastData = null;
					$('#rF').hide();
					$('#wF').show();
				}
				else if (xhr.status == 413) {
					$('#rF').hide();
					$('#wF').show();
					ex._rWriteErr('Your value is too big. Please edit it.');
				}
				else {
					ex._lastData = null;
					$('#rF').hide();
					$('#wF').show();
					ex._rWriteErr();
				}
			},
			complete: function(xhr, textStatus) {
				ex._hLoading();
				ex._curReq = null;
			}
		});
		return false;
	},
	_sLoading: function() {
		$('#loading').fadeIn('slow', function() { if (ex._curReq == null) { ex._hLoading(); } });
	},
	_hLoading: function() {
		$('#loading').hide();
	},
	normKey: function(s) {
		if (!s || s.match(ex.WS_RE)) {
			return null;
		}
		for (c in s) {
			var code = s.charCodeAt(c);
			if (code < 128) {
				if (!s[c].match(ex.ALNUM_RE)) { 
					s = s.substr(0, c) + '-' + s.substr(++c);
				}
			}
		}
		s = s.replace(/--+/g, '-');
		s = s.replace(/-+$/, '');
		return s.toLowerCase();
	},
	_clearErrs: function() {
		$('#rF #rErr').html('');
		$('#editL').show();
		$('#wF #wErr').html('');
		$('#wF #exValueLabel').html(ex.DEF_V_CAP);
	},
	_rWriteErr: function(msg, labelText) {
		$('#rF').hide();
		if (msg == null) {
			msg = ex.DEF_ERR;
		}
		$('#wF #wErr').html(msg);
		if (labelText == null) {
			labelText = ex.DEF_V_CAP;
		}
		$('#wF #exValueLabel').html(labelText);
		$('#wF').show();
	},
	_rReadErr: function(msg) {
		$('#wF').hide();
		if (msg == null) {
			msg = ex.DEF_ERR;
		}
		$('#rF #content .inner').html('');
		$('#rF #rErr').html(msg);
		$('#editL').hide();
		$('#rF').show();
	},
	_rWrite: function(exValue, showCancel, caption) {
		$('#wF #wErr').html('');
		$('#wF #exValue').val(exValue);
		if (!caption) {
			caption = ex.DEF_V_CAP;
		}
		$('#wF #exValueLabel').html(caption);
		if (showCancel) {
			$('#wF #cancelBut').show();
		}
		else {
			$('#wF #cancelBut').hide();
		}
		$('#rF').hide();
		$('#wF').show();
	},
	_rRead: function(data, type) {
		$('#wF').hide();
		var el = $('#rF #content .inner');
		el.html('').append(document.createTextNode(data));
		el.html(el.html().replace(ex.NL_RE, '<br/>'));
		$('#rF').slideDown('fast');
	}
}
}();
$(document).ready(function() { ex.init(); });
</script>
<style type="text/css">body{font:100% "georgia","times new roman",times,serif /1.5;color:#444;text-align:left}body,#rF{background:#fff}html>body{font-size:100%}#wrapper{width:35em;position:relative}#wrapper h1{font-size:2.0;margin-left:2.0em;min-height:2.25em}#wrapper input.text{border:1px solid #999;padding:3px;width:18em}#wrapper label,#wF #wErr{font:80% tahoma,sans-serif}#wrapper label{padding-right:3px}#commonF{position:absolute;top:2.75em;left:4.25em;padding-bottom:0.75em;border-bottom:1px dotted #666}#commonF,#wF textarea{width:42em}#rF,#wF,#loading{display:none}#rF{margin-left:4.25em;font-size:100%}#rF #rErr{font:85% tahoma,sans-serif;padding-left:8px}#rF #rErr,#wF #wErr{color:#a00;padding-top:6px;}#rF .inner{padding:6px;font-family:"courier new",courier,monospace;line-height:1.2;}#wF{margin-left:4.55em}#wF label,#wF textarea,#loading img{display:block}#loading {margin-left:5.25em;margin-top:3em;font:80% tahoma,sans-serif;}#toolbar{text-align:right;margin-top:-0.7em;}#toolbar a{font:75% tahoma,sans-serif;background:#ccc;padding:2px 8px;border:1px dotted #666;border-top-width:0;text-decoration:none;color:#00a;}#toolbar a:hover{text-decoration:underline;border-style:solid;}</style>
</head>
<body>
<div id="wrapper">
<h1>Exarcheia</h1>
<form id="mainForm" method="post" action="#" onsubmit="return false">
<div id="commonF">
	<label for="exKey" class="exKey"></label>
	<input type="text" class="text" name="exKey" id="exKey" maxlength="8192" size="20"/>
	<input type="submit" id="fetchBut" class="submit" value="Fetch"/>
</div>
<div id="rF">
	<div id="toolbar"><a href="#" id="editL">Edit</a></div>
	<div id="rErr"></div>
	<div id="content">
		<div class="inner">
		</div>
	</div>
</div>
<div id="wF">
	<div id="wErr"></div>
	<label for="exValue" id="exValueLabel">This entry does not exist; create it below:</label>
	<textarea name="exValue" id="exValue" rows="20" cols="40"></textarea>
	<input type="submit" id="saveBut" class="submit" value="Save"/>
	<input type="button" id="cancelBut" class="button" value="Cancel"/>
</div>
<div id="loading">
	Loading...
</div>
</form>
</div>
</body>
</html>
